package org.posupe.pessoas;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.posupe.bdr.PersistenceMechanismException;
import org.posupe.bdr.PersistenceMechanismRDBMS;
import org.posupe.empresas.Empresa;
import org.posupe.empresas.EmpresaInexistenteException;
import org.posupe.util.Endereco;
import org.posupe.util.RepositorioException;

/**
 * @author Marcio Calado
 */
public class RepositorioPessoasBDR{

	private static RepositorioPessoasBDR instance;
	private PersistenceMechanismRDBMS pm;

	private static final String TIPO_EMPRESA = "E";
	private static final String TIPO_CANDIDATO = "C";

	private static String SQL_INSERT = "INSERT INTO PESSOA (CODIGO,NOME,CEP,LOGRADOURO,NUMERO,COMPLEMENTO,BAIRRO,CIDADE,ESTADO,PAIS,TIPO) VALUES (?,?,?,?,?,?,?,?,?,?,?)";
	private static String SQL_REMOVE = "DELETE * FROM PESSOA WHERE codigo = ?";
	private static String SQL_UPDATE = "UPDATE PESSOA SET NOME = ? WHERE CODIGO = ? ";
	private static String SQL_SELECT_WHERE = "SELECT CODIGO,NOME,CEP,LOGRADOURO,NUMERO,COMPLEMENTO,BAIRRO,CIDADE,ESTADO,PAIS,TIPO FROM PESSOA WHERE CODIGO = ? ";
	//private static String SQL_SELECT = "SELECT * FROM PESSOA WHERE CODIGO = ?";

	private RepositorioPessoasBDR() throws RepositorioException {
		try {
			pm = PersistenceMechanismRDBMS.getInstance();
			pm.connect();
		}
		catch (Exception ex) {
			throw new RepositorioException(ex);
		}
	}

	public synchronized static RepositorioPessoasBDR getInstance() throws RepositorioException {
		if (instance == null) {
			instance = new RepositorioPessoasBDR();

		}
		return instance;
	}

	public void inserir(Pessoa pessoa) throws RepositorioException {
		try {
			PreparedStatement statement = (PreparedStatement) pm.getCommunicationChannel(SQL_INSERT);
			statement.setString(1, pessoa.getCodigo());
			statement.setString(2, pessoa.getNome());

			statement.setString(3, pessoa.getEndereco()==null?null:pessoa.getEndereco().getCep());
			statement.setString(4, pessoa.getEndereco()==null?null:pessoa.getEndereco().getLogradouro());
			statement.setInt(5, pessoa.getEndereco()==null?0:pessoa.getEndereco().getNumero().intValue());
			statement.setString(6, pessoa.getEndereco()==null?null:pessoa.getEndereco().getComplemento());
			statement.setString(7, pessoa.getEndereco()==null?null:pessoa.getEndereco().getBairro());
			statement.setString(8, pessoa.getEndereco()==null?null:pessoa.getEndereco().getCidade());
			statement.setString(9, pessoa.getEndereco()==null?null:pessoa.getEndereco().getEstado());
			statement.setString(10, pessoa.getEndereco()==null?null:pessoa.getEndereco().getPais());

			if(pessoa instanceof Empresa){
				statement.setString(11, TIPO_EMPRESA);
			}else {
				statement.setString(11, TIPO_CANDIDATO);
			}        				

			statement.executeUpdate();

		} catch(PersistenceMechanismException e){
			throw new RepositorioException(e);
		} catch (SQLException e) {
			throw new RepositorioException(e);
		} finally {
			try {
				pm.releaseCommunicationChannel();
			} catch (PersistenceMechanismException ex) {
				throw new RepositorioException(ex);
			}
		}
	}

	public void remover(String codigo) throws RepositorioException, EmpresaInexistenteException {
		try{
			PreparedStatement statement = (PreparedStatement) pm.getCommunicationChannel(SQL_REMOVE);
			statement.setString(1, codigo);
			int i = statement.executeUpdate();
			if (i == 0) {
				throw new EmpresaInexistenteException(codigo);
			}
		} catch(PersistenceMechanismException e){
			throw new RepositorioException(e);
		} catch(SQLException e){
			throw new RepositorioException(e);            
		} finally {
			try {
				pm.releaseCommunicationChannel();
			} catch (PersistenceMechanismException ex) {
				throw new RepositorioException(ex);
			}
		}
	}

	public Pessoa procurar(String codigo) throws EmpresaInexistenteException, RepositorioException {
		Pessoa pessoa = null;
		try {
			PreparedStatement statement = (PreparedStatement) pm.getCommunicationChannel(SQL_SELECT_WHERE);
			statement.setString(1, codigo);
			ResultSet resultset = statement.executeQuery();
			if (resultset.next()) {
				if(resultset.getString("TIPO").equals(TIPO_EMPRESA)){
					pessoa = new Empresa(resultset.getString("CODIGO"));
				}else if(resultset.getString("TIPO").equals(TIPO_CANDIDATO)){
					pessoa = new Empresa(resultset.getString("CODIGO"));
				}
				Endereco endereco = new Endereco(resultset.getString("CEP"),resultset.getString("LOGRADOURO"),new Integer(resultset.getInt("NUMERO")),
						resultset.getString("COMPLEMENTO"),resultset.getString("BAIRRO"),resultset.getString("CIDADE"),
						resultset.getString("ESTADO"),resultset.getString("PAIS"));
				pessoa.setEndereco(endereco);
			} else {
				throw new EmpresaInexistenteException(codigo);
			}
			resultset.close();
		} catch(PersistenceMechanismException e){
			throw new RepositorioException(e);
		} catch (SQLException e) {
			throw new RepositorioException(e);
		} finally {
			try {
				pm.releaseCommunicationChannel();
			} catch (PersistenceMechanismException ex) {
				throw new RepositorioException(ex);
			}
		}
		return pessoa;
	}

	public void atualizar(Pessoa pessoa) throws PessoaInexistenteException, RepositorioException {
		try{
		PreparedStatement statement = (PreparedStatement) pm.getCommunicationChannel(SQL_UPDATE);

		statement.setString(1, pessoa.getNome());			
		statement.setString(2, pessoa.getEndereco()==null?null:pessoa.getEndereco().getCep());
		statement.setString(3, pessoa.getEndereco()==null?null:pessoa.getEndereco().getLogradouro());
		statement.setInt(4, pessoa.getEndereco()==null?0:pessoa.getEndereco().getNumero().intValue());
		statement.setString(5, pessoa.getEndereco()==null?null:pessoa.getEndereco().getComplemento());
		statement.setString(6, pessoa.getEndereco()==null?null:pessoa.getEndereco().getBairro());
		statement.setString(7, pessoa.getEndereco()==null?null:pessoa.getEndereco().getCidade());
		statement.setString(8, pessoa.getEndereco()==null?null:pessoa.getEndereco().getEstado());
		statement.setString(9, pessoa.getEndereco()==null?null:pessoa.getEndereco().getPais());

		statement.setString(10, pessoa.getCodigo());
		if(pessoa instanceof Empresa){
			statement.setString(11, TIPO_EMPRESA);
		}else {
			statement.setString(11, TIPO_CANDIDATO);
		}        				

		statement.executeUpdate();

		} catch(PersistenceMechanismException e){
			throw new RepositorioException(e);
		} catch (SQLException e) {
			throw new RepositorioException(e);
		} finally {
			try {
				pm.releaseCommunicationChannel();
			} catch (PersistenceMechanismException ex) {
				throw new RepositorioException(ex);
			}
		}

	}

	public boolean existe(String codigo) throws RepositorioException {
		boolean resposta = false;
		try {

			PreparedStatement statement = (PreparedStatement) pm.getCommunicationChannel(SQL_SELECT_WHERE);
			statement.setString(1, codigo);
			ResultSet resultset = statement.executeQuery();
			resposta = resultset.next();
			resultset.close();
		} catch(PersistenceMechanismException e){
			throw new RepositorioException(e);
		} catch (SQLException e) {
			throw new RepositorioException(e);
		} finally {
			try {
				pm.releaseCommunicationChannel();
			} catch (PersistenceMechanismException ex) {
				throw new RepositorioException(ex);
			}
		}
		return resposta;
	}

}